{ "success": true, "task_id": "f45388a9-4169-41d4-aec8-fb8259c48d36", "trace_id": "1df9f664-fd74-476b-8038-b0b5f62ddf87", "data": [ { "id": "02702b40-272d-4838-8644-675105930658", "title": "Vibe", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/e850008a-d9a1-4c8f-acbd-a37f228946bc/image/02702b40-272d-4838-8644-675105930658.jpg", "lyric": "[Intro]\nYeah, yeah\nKeep talking, keep talking\nI love the way you sound\n[Verse 1]\nYour voice is like a drug I can't put down\nEvery word you say just pulls me in\nI'm addicted to the way you laugh out loud\nAnd how you whisper when the room goes dim\nTell me 'bout your day, tell me 'bout your fears\nI could listen to you talk for years\n[Pre-Chorus]\nDon't stop now, don't you dare\nI need your voice filling up the air\n[Chorus]\nKeep talking, keep talking to me\nYour words are all I fucking need\nKeep talking, keep talking, I'm high\nOff every sound you make tonight\nKeep talking\n[Verse 2]\nYou could read the phone book, I don't care\nJust the rhythm of your breathing's enough\nWhen you say my name, it's like a prayer\nAnd your silence hits me twice as rough\nEvery conversation feels like home\nNever want to hear this dial tone\n[Pre-Chorus]\nDon't stop now, don't you dare\nI need your voice filling up the air\n[Chorus]\nKeep talking, keep talking to me\nYour words are all I fucking need\nKeep talking, keep talking, I'm high\nOff every sound you make tonight\nKeep talking\n[Bridge]\nWhen the world gets loud and crazy\nYour voice cuts through the noise\nYou're my favorite conversation\nYou're my drug of choice\nKeep talking, keep talking\nKeep talking, keep talking\nKeep talking, keep talking\nKeep talking, keep talking\n[Chorus]\nKeep talking, keep talking to me\nYour words are all I fucking need\nKeep talking, keep talking, I'm high\nOff every sound you make tonight\nKeep talking\n[Outro]\nYeah, yeah\nKeep talking, keep talking\nNever stop that sound", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/e850008a-d9a1-4c8f-acbd-a37f228946bc/audio/02702b40-272d-4838-8644-675105930658.m4a", "video_url": null, "created_at": "2025-06-18T15:47:54.705246Z", "model": "FUZZ-1.0", "lyrics_timestamped": { "words": [ { "text": "[Intro]", "start": 0.64, "end": 0.64, "line_index": 0, "index_range": null, "wav2vec2_format": null }, ... { "text": "sound", "start": 179.84, "end": 180.48, "line_index": 63, "index_range": null, "wav2vec2_format": null } ] }, "state": "succeeded", "style": "Pop, upbeat tempo, modern production", "duration": 181.12 }, { "id": "be3fe757-621e-4017-9056-20aa7f01919e", "title": "Revive", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/e850008a-d9a1-4c8f-acbd-a37f228946bc/image/be3fe757-621e-4017-9056-20aa7f01919e.jpg", "lyric": "[Verse 1]\nI'm walking through the motions, moving day by day\nColors seem a little faded, nothing much to say\nFriends keep calling, asking if I'm doing fine\nBut I just smile and tell them everything's divine\n[Pre-Chorus]\nSomething's missing, can't quite name it\nFeels like I'm just going through the stages\n[Chorus]\nI'm barely breathing, barely feeling\nLike I'm floating through a life that isn't mine\nBarely breathing, barely healing\nSearching for a reason, searching for a sign\nTo feel alive again\nTo feel alive again\n[Verse 2]\nMorning coffee tastes like water, sunrise looks like rain\nEveryone around me laughs but I can't feel the same\nUsed to dance in silly moments, used to sing out loud\nNow I'm standing in the silence of a faceless crowd\n[Pre-Chorus]\nSomething's shifting, can't ignore it\nMaybe it's time to break these patterns\n[Chorus]\nI'm barely breathing, barely feeling\nLike I'm floating through a life that isn't mine\nBarely breathing, barely healing\nSearching for a reason, searching for a sign\nTo feel alive again\nTo feel alive again\n[Bridge]\nBut there's a beating in my chest\nA whisper saying \"don't give up yet\"\nMaybe tomorrow I'll remember\nHow to laugh and how to let\nMy heart wake up from this long sleep\nFind the fire I used to keep\n[Chorus]\nI'm barely breathing, barely feeling\nLike I'm floating through a life that isn't mine\nBarely breathing, barely healing\nSearching for a reason, searching for a sign\nTo feel alive again\nTo feel alive again\n[Outro]\nI'm gonna feel alive again\nI'm gonna feel alive again", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/e850008a-d9a1-4c8f-acbd-a37f228946bc/audio/be3fe757-621e-4017-9056-20aa7f01919e.m4a", "video_url": null, "created_at": "2025-06-18T15:48:01.139081Z", "model": "FUZZ-1.0", "lyrics_timestamped": { "words": [ { "text": "[Verse", "start": 0.64, "end": 0.64, "line_index": 0, "index_range": null, "wav2vec2_format": null }, ... { "text": "again", "start": 202.88, "end": 211.84, "line_index": 54, "index_range": null, "wav2vec2_format": null } ] }, "state": "succeeded", "style": "Pop, upbeat tempo, clean production, emotional vocals", "duration": 211.84 } ] }
返回結(jié)果一共有多個字段,介紹如下:
success,此時音樂生成任務的狀態(tài)情況。
data,此次音樂任務的結(jié)果 - id,此時音樂生成任務的 ID。
prompt,此時音樂生成任務的提示詞。
audio_url,此時音樂生成任務的音頻鏈接。
image_url,此時音樂生成任務的封面鏈接。
state,此時音樂生成任務的狀態(tài)。
duration,此時音樂的時長信息。
style,此時音樂的風格信息。
model,此時音樂生成任務采用的模型信息。
lyric,此時音樂生成任務的歌詞信息。
可以看到我們得到了想生成的音樂信息,我們只需要根據(jù)結(jié)果中 data 的音樂鏈接地址獲取生成的 Riffusion 音樂即可。
另外如果想生成對應的對接代碼,可以直接復制生成,例如 CURL 的代碼如下:
1 2 3 4 5 6 7 8 9
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "FUZZ-1.0", "action": "generate", "prompt": "A song for Christmas" }'
自定義生成
如果想自定義生成歌詞,可以輸入歌詞:
這時候 lyric 字段可以傳入類似如下內(nèi)容:
1
[Verse]Woke up withthe sun inmy eyesNo clouds above just blue inthe skiesShoes onmy feet I’m ready to runEvery step feels like a loaded gun[Chorus]Happy days are rolling inLet the joy beneathmy skinNo more shadows no more liesJust the truth that lifts me high[Verse 2]Dancing throughthe city streetsA rhythm pounding inmy heartbeatStrangers smile it’s catching onThis world’s a stage we’re all a song[Chorus]Happy days are rolling inLet the joy beneathmy skinNo more shadows no more liesJust the truth that lifts me high[Bridge]Throw your worries out the doorLet them sink tothe ocean floorWe’re alive andit’s enoughLife is messy butit’s love[Chorus]Happy days are rolling inLet the joy beneathmy skinNo more shadows no more liesJust the truth that lifts me high
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "FUZZ-1.0", "action": "generate", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "custom": true }'
{ "success": true, "task_id": "978c2912-6a90-4048-b4c1-43f9cf18c28d", "trace_id": "08dfbb99-43ce-4f65-8fd1-74b98f2b121a", "data": [ { "id": "eac9ab69-e210-490b-9f8d-095a6f074f40", "title": "VibeRise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3f3e1354-52ad-4f5b-902c-5f83abd17def/image/eac9ab69-e210-490b-9f8d-095a6f074f40.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3f3e1354-52ad-4f5b-902c-5f83abd17def/audio/eac9ab69-e210-490b-9f8d-095a6f074f40.m4a", "video_url": null, "created_at": "2025-06-23T01:57:33.438644Z", "model": "FUZZ-1.0", "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, { "end": 0.64, "index_range": null, "line_index": 1, "start": 0.64, "text": "Woke", "wav2vec2_format": null }, ... ] }, "state": "succeeded", "style": "funk vibes, raspy, raw vocal texture", "duration": 158.08 }, { "id": "64fffe1f-b1aa-46dc-8012-b80ba319cf35", "title": "Pure Dawn", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3f3e1354-52ad-4f5b-902c-5f83abd17def/image/64fffe1f-b1aa-46dc-8012-b80ba319cf35.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3f3e1354-52ad-4f5b-902c-5f83abd17def/audio/64fffe1f-b1aa-46dc-8012-b80ba319cf35.m4a", "video_url": null, "created_at": "2025-06-23T01:57:33.963497Z", "model": "FUZZ-1.0", "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, { "end": 0.64, "index_range": null, "line_index": 1, "start": 0.64, "text": "Woke", "wav2vec2_format": null }, ... ] }, "state": "succeeded", "style": "contemporary country", "duration": 175.36 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "cover", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c" }'
{ "success": true, "task_id": "fe02997d-f58e-4886-9aa3-4074c9a430eb", "trace_id": "997bde4c-6063-4fc2-9b03-d837f1efc72d", "data": [ { "id": "be254182-d4b7-42b3-9ee2-b86db086cff1", "title": "Sunny Rise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/c2f707a9-017d-4354-8bfa-436266dadbf6/image/be254182-d4b7-42b3-9ee2-b86db086cff1.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/c2f707a9-017d-4354-8bfa-436266dadbf6/audio/be254182-d4b7-42b3-9ee2-b86db086cff1.m4a", "video_url": null, "created_at": "2025-06-23T01:59:17.666629Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 237.44, "index_range": null, "line_index": 29, "start": 236.8, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 239.46235827664398 }, { "id": "9b9d2810-eb2b-44d3-85c0-cb259afa13c3", "title": "Uplift", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/c2f707a9-017d-4354-8bfa-436266dadbf6/image/9b9d2810-eb2b-44d3-85c0-cb259afa13c3.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/c2f707a9-017d-4354-8bfa-436266dadbf6/audio/9b9d2810-eb2b-44d3-85c0-cb259afa13c3.m4a", "video_url": null, "created_at": "2025-06-23T01:59:23.065712Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, ... }, { "end": 236.16, "index_range": null, "line_index": 29, "start": 225.28, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 239.5299546485261 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "extend", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c", "continue_at": 5 }'
{ "success": true, "task_id": "6388a0aa-b5ab-4485-baad-f0e0b7a7848c", "trace_id": "da143dbe-8263-45ac-b05a-1ed57dd4aa79", "data": [ { "id": "209e27e0-500c-44f3-9134-280690014920", "title": "City Rhythm", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3a8378d5-94d4-49b7-9c0a-8432c0c4a39d/image/209e27e0-500c-44f3-9134-280690014920.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3a8378d5-94d4-49b7-9c0a-8432c0c4a39d/audio/209e27e0-500c-44f3-9134-280690014920.m4a", "video_url": null, "created_at": "2025-06-23T02:00:53.473604Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 4.48, "index_range": null, "line_index": 0, "start": 4.48, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 179.2, "index_range": null, "line_index": 29, "start": 178.56, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 197.00850340136054 }, { "id": "ff50012e-ad1b-4b71-8d0e-6a633428a54f", "title": "Bright", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3a8378d5-94d4-49b7-9c0a-8432c0c4a39d/image/ff50012e-ad1b-4b71-8d0e-6a633428a54f.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3a8378d5-94d4-49b7-9c0a-8432c0c4a39d/audio/ff50012e-ad1b-4b71-8d0e-6a633428a54f.m4a", "video_url": null, "created_at": "2025-06-23T02:00:52.795796Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 186.88, "index_range": null, "line_index": 29, "start": 186.24, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 213.85757369614512 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "replace_section", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c", "replace_section_start": 3, "replace_section_end": 70 }'
{ "success": true, "task_id": "73defcbf-f876-4dd6-b60e-4c1c5ecd4565", "trace_id": "9f639389-7218-4cdb-ade9-b34228bb0f21", "data": [ { "id": "037f5e9d-9da4-4d79-b58f-1f433b40d54d", "title": "Sunrise Joy", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/881ad27f-39c1-4c31-a789-ecc822e13b8c/image/037f5e9d-9da4-4d79-b58f-1f433b40d54d.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/881ad27f-39c1-4c31-a789-ecc822e13b8c/audio/037f5e9d-9da4-4d79-b58f-1f433b40d54d.m4a", "video_url": null, "created_at": "2025-06-23T02:18:43.031184Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 3.84, "index_range": null, "line_index": 0, "start": 3.84, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 159.36, "index_range": null, "line_index": 29, "start": 159.36, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 199.2201133786848 }, { "id": "97638295-068f-4cbc-b076-66f522449bd5", "title": "Sunrise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/881ad27f-39c1-4c31-a789-ecc822e13b8c/image/97638295-068f-4cbc-b076-66f522449bd5.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/881ad27f-39c1-4c31-a789-ecc822e13b8c/audio/97638295-068f-4cbc-b076-66f522449bd5.m4a", "video_url": null, "created_at": "2025-06-23T02:18:56.267775Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 3.84, "index_range": null, "line_index": 0, "start": 3.84, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 159.36, "index_range": null, "line_index": 29, "start": 159.36, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 199.2201133786848 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "swap_sound", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c" }'
{ "success": true, "task_id": "93279260-5ca1-42d8-bde1-1fa62e0f5027", "trace_id": "bc4e28db-4897-4ffc-9e03-45f43da7a21c", "data": [ { "id": "242035c0-8ac2-4f0b-a19c-ac2fa49d4df3", "title": "Brightside", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/36494e8a-eb82-4d89-bbfa-ec719e19572b/image/242035c0-8ac2-4f0b-a19c-ac2fa49d4df3.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/36494e8a-eb82-4d89-bbfa-ec719e19572b/audio/242035c0-8ac2-4f0b-a19c-ac2fa49d4df3.m4a", "video_url": null, "created_at": "2025-06-23T02:02:32.799561Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 1.28, "index_range": null, "line_index": 0, "start": 1.28, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 195.84, "index_range": null, "line_index": 29, "start": 195.84, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 197.2696371882086 }, { "id": "594fe702-6c71-4b0c-abb6-21b58efc74a6", "title": "Sunrise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/36494e8a-eb82-4d89-bbfa-ec719e19572b/image/594fe702-6c71-4b0c-abb6-21b58efc74a6.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/36494e8a-eb82-4d89-bbfa-ec719e19572b/audio/594fe702-6c71-4b0c-abb6-21b58efc74a6.m4a", "video_url": null, "created_at": "2025-06-23T02:02:30.523279Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 192.64, "index_range": null, "line_index": 29, "start": 192.64, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 196.7198866213152 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "swap_vocals", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c" }'
{ "success": true, "task_id": "a6e0d456-189b-4c78-9232-2fe72166ab39", "trace_id": "ee5769d4-ae94-4e5a-a85f-b3c0ddc2e48e", "data": [ { "id": "b8b1ed14-f43c-4738-a697-60ba24b6049d", "title": "Uplift", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/25ce4ddd-e48c-42e2-9ea3-8e03380508f2/image/b8b1ed14-f43c-4738-a697-60ba24b6049d.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/25ce4ddd-e48c-42e2-9ea3-8e03380508f2/audio/b8b1ed14-f43c-4738-a697-60ba24b6049d.m4a", "video_url": null, "created_at": "2025-06-23T02:04:18.477032Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 2.56, "index_range": null, "line_index": 0, "start": 2.56, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 186.88, "index_range": null, "line_index": 29, "start": 171.52, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 195.55968253968254 }, { "id": "dfd6eb9c-a1f3-4e1f-bbf9-e0b9625e459f", "title": "Vivid Rise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/25ce4ddd-e48c-42e2-9ea3-8e03380508f2/image/dfd6eb9c-a1f3-4e1f-bbf9-e0b9625e459f.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/25ce4ddd-e48c-42e2-9ea3-8e03380508f2/audio/dfd6eb9c-a1f3-4e1f-bbf9-e0b9625e459f.m4a", "video_url": null, "created_at": "2025-06-23T02:04:27.140387Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 1.28, "index_range": null, "line_index": 0, "start": 1.28, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 188.8, "index_range": null, "line_index": 29, "start": 188.16, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 196.07185941043085 } ] }
異步回調(diào)
由于 Riffusion Audios Generation API 生成的時間有時候會相對較長,如果 API 長時間無響應,HTTP 請求會一直保持連接,導致額外的系統(tǒng)資源消耗,所以本 API 也提供了異步回調(diào)的支持。
整體流程是:客戶端發(fā)起請求的時候,額外指定一個 callback_url 字段,客戶端發(fā)起 API 請求之后,API 會立馬返回一個結(jié)果,包含一個 task_id 的字段信息,代表當前的任務 ID。當任務完成之后,生成任務的結(jié)果會通過 POST JSON 的形式發(fā)送到客戶端指定的 callback_url,其中也包括了 task_id 字段,這樣任務結(jié)果就可以通過 ID 關聯(lián)起來了。
{ "success": true, "task_id": "9939767a-7f9c-4f43-aabf-ca68fe385f3c", "trace_id": "13a86870-e705-45d0-8447-82a08701c0fa", "data": [ { "id": "72e6c476-0116-4da9-ae34-f78190020b35", "title": "Rise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/9b9f3281-6b47-44ac-8e4b-3b0d105e163d/image/72e6c476-0116-4da9-ae34-f78190020b35.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/9b9f3281-6b47-44ac-8e4b-3b0d105e163d/audio/72e6c476-0116-4da9-ae34-f78190020b35.m4a", "video_url": null, "created_at": "2025-06-15T15:43:22.432605Z", "model": "FUZZ-1.0", "state": "succeeded", "style": "acoustic folk, finger picking", "duration": 184.96 }, { "id": "7f4f5c20-4395-4583-9dbb-735b9bb86957", "title": "Luminance", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/9b9f3281-6b47-44ac-8e4b-3b0d105e163d/image/7f4f5c20-4395-4583-9dbb-735b9bb86957.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/9b9f3281-6b47-44ac-8e4b-3b0d105e163d/audio/7f4f5c20-4395-4583-9dbb-735b9bb86957.m4a", "video_url": null, "created_at": "2025-06-15T15:43:21.574561Z", "model": "FUZZ-1.0", "state": "succeeded", "style": "deep bass, ethereal electronic", "duration": 165.12 } ] }
我們還可以通過 position 參數(shù)控制二維碼的位置,比如說一張圖片里面有一個女生穿裙子,而我們想要把二維碼放在裙子的位置并與之融合起來,我們就可以嘗試改下二維碼的位置,調(diào)用樣例如下:
1 2 3 4 5 6 7 8 9 10
curl -X POST "https://api.zhishuyun.com/qrart/generate?token={token}" \ -H "accept: application/json" \ -H "content-type: application/json" \ -d '{ "type": "link", "content": "https://data.zhishuyun.com", "prompt": "one of the beautiful girls in the moonlight in the background, in the style of pixelated chaos, rococo-inspired art, dark white and sky-blue, made of plastic, delicate flowers, gongbi, wimmelbilder", "position": "bottom", "aspect_ratio": "576x1008" }'
Nexior 是 GitHub 上的一個開源項目,利用它我們可以一鍵部署自己的 AI 應用站點,包括 AI 問答、Midjourney 繪畫、知識庫問答、藝術(shù)二維碼等應用,無需自己開發(fā) AI 系統(tǒng)、無需采購 AI 賬號、無需關心 API 支持、無需配置支付系統(tǒng),零啟動成本,無風險通過 AI 賺取收益。
本文章會介紹 Nexior 項目在 Vercel 上的部署流程,無需任何編程技巧即可幾分鐘部署一套屬于自己的 AI 站點,并輕松利用該站點獲取收益。
隨著 AI 的應用變廣,各類 AI 程序已逐漸普及。AI 已逐漸深入到人們的工作生活方方面面。而 AI 涉及的行業(yè)也越來越多,從最初的寫作,到醫(yī)療教育,再到現(xiàn)在的音樂。
Suno 是一個專業(yè)高質(zhì)量的 AI 歌曲和音樂創(chuàng)作平臺,用戶只需輸入簡單的文本提示詞,即可根據(jù)流派風格和歌詞生成帶有人聲的歌曲。該 AI 音樂生成器由來自 Meta、TikTok、Kensho 等知名科技公司的團隊成員開發(fā),目標是不需要任何樂器工具,讓所有人都可以創(chuàng)造美妙的音樂。
{ "success": true, "data": [ { "id": "2f16f7bc-4135-42c6-b3c5-6d6c49dc8cd5", "title": "Winter Wonderland", "image_url": "https://cdn1.suno.ai/image_2f16f7bc-4135-42c6-b3c5-6d6c49dc8cd5.png", "lyric": "[Verse]\nSnowflakes falling all around\nGlistening white\nCovering the ground\nChildren laughing\nFull of delight\nIn this winter wonderland tonight\nSanta's sleigh\nUp in the sky\nRudolph's nose shining bright\nOh my\nHear the jingle bells\nRinging so clear\nBringing joy and holiday cheer\n[Verse 2]\nRoasting chestnuts by the fire's glow\nChristmas lights\nThey twinkle and show\nFamilies gathering with love and cheer\nSpreading warmth to everyone near", "audio_url": "https://cdn1.suno.ai/2f16f7bc-4135-42c6-b3c5-6d6c49dc8cd5.mp3", "video_url": "https://cdn1.suno.ai/2f16f7bc-4135-42c6-b3c5-6d6c49dc8cd5.mp4", "created_at": "2024-05-10T16:21:37.624Z", "model": "chirp-v3", "prompt": "A song for Christmas", "style": "holiday" }, { "id": "5dca232b-17cc-4896-a2d1-4b59178bf410", "title": "Winter Wonderland", "image_url": "https://cdn1.suno.ai/image_5dca232b-17cc-4896-a2d1-4b59178bf410.png", "lyric": "[Verse]\nSnowflakes falling all around\nGlistening white\nCovering the ground\nChildren laughing\nFull of delight\nIn this winter wonderland tonight\nSanta's sleigh\nUp in the sky\nRudolph's nose shining bright\nOh my\nHear the jingle bells\nRinging so clear\nBringing joy and holiday cheer\n[Verse 2]\nRoasting chestnuts by the fire's glow\nChristmas lights\nThey twinkle and show\nFamilies gathering with love and cheer\nSpreading warmth to everyone near", "audio_url": "https://cdn1.suno.ai/5dca232b-17cc-4896-a2d1-4b59178bf410.mp3", "video_url": "https://cdn1.suno.ai/5dca232b-17cc-4896-a2d1-4b59178bf410.mp4", "created_at": "2024-05-10T16:21:37.624Z", "model": "chirp-v3", "prompt": "A song for Christmas", "style": "holiday" } ] }
[Verse]\nSnowflakes falling all around\nGlistening white\nCovering the ground\nChildren laughing\nFull of delight\nIn this winter wonderland tonight\nSanta's sleigh\nUp in the sky\nRudolph's nose shining bright\nOh my\nHear the jingle bells\nRinging so clear\nBringing joy and holiday cheer\n[Verse 2]\nRoasting chestnuts by the fire's glow\nChristmas lights\nThey twinkle and show\nFamilies gathering with love and cheer\nSpreading warmth to everyone near
注意,這里的歌詞中 \n 是換行符,如果你不知道如何生成歌詞,可以使用下文介紹的生成歌詞的 API 自助生成。
curl -X POST 'https://api.acedata.cloud/suno/audios' \ -H 'authorization: Bearer {token}' \ -H 'accept: application/json' \ -H 'content-type: application/json' \ -d '{ "lyric": "[Verse]\\nSnowflakes falling all around\\nGlistening white\\nCovering the ground\\nChildren laughing\\nFull of delight\\nIn this winter wonderland tonight\\nSanta's sleigh\\nUp in the sky\\nRudolph's nose shining bright\\nOh my\\nHear the jingle bells\\nRinging so clear\\nBringing joy and holiday cheer\\n[Verse 2]\\nRoasting chestnuts by the fire's glow\\nChristmas lights\\nThey twinkle and show\\nFamilies gathering with love and cheer\\nSpreading warmth to everyone near", "custom": true }'
測試允許,生成的效果是類似的。
異步回調(diào)
由于 Suno 生成音樂的時間相對較長,大約需要 1-2 分鐘,如果 API 長時間無響應,HTTP 請求會一直保持連接,導致額外的系統(tǒng)資源消耗,所以本 API 也提供了異步回調(diào)的支持。
整體流程是:客戶端發(fā)起請求的時候,額外指定一個 callback_url 字段,客戶端發(fā)起 API 請求之后,API 會立馬返回一個結(jié)果,包含一個 task_id 的字段信息,代表當前的任務 ID。當任務完成之后,生成音樂的結(jié)果會通過 POST JSON 的形式發(fā)送到客戶端指定的 callback_url,其中也包括了 task_id 字段,這樣任務結(jié)果就可以通過 ID 關聯(lián)起來了。
{ "success": true, "task_id": "44472ab8-783b-4054-b861-5bf14e462f60", "data": [ { "id": "da4324e5-84b2-484b-b0e9-dd261381c594", "title": "Winter Whispers", "image_url": "https://cdn1.suno.ai/image_da4324e5-84b2-484b-b0e9-dd261381c594.png", "lyric": "[Verse]\nSnow falling gently from the sky\nChildren giggling as they pass by\nFire crackling\nCozy and warm\nChristmas spirit begins to swarm\n[Verse 2]\nTwinkling lights\nA sight to behold\nStockings hung\nWaiting to be filled with gold\nGifts wrapped with love\nPiled high\nExcitement in the air\nYou can't deny\n[Chorus]\nWinter whispers in the wind\nJoy and love it brings\nLet's celebrate this season\nWith the ones we're missing", "audio_url": "https://cdn1.suno.ai/da4324e5-84b2-484b-b0e9-dd261381c594.mp3", "video_url": "https://cdn1.suno.ai/da4324e5-84b2-484b-b0e9-dd261381c594.mp4", "created_at": "2024-05-11T07:33:05.430Z", "model": "chirp-v3", "prompt": "A song for Christmas", "style": "pop" }, { "id": "b878a87b-a0db-4046-8ccd-ecd2fb3d4372", "title": "Winter Whispers", "image_url": "https://cdn1.suno.ai/image_b878a87b-a0db-4046-8ccd-ecd2fb3d4372.png", "lyric": "[Verse]\nSnow falling gently from the sky\nChildren giggling as they pass by\nFire crackling\nCozy and warm\nChristmas spirit begins to swarm\n[Verse 2]\nTwinkling lights\nA sight to behold\nStockings hung\nWaiting to be filled with gold\nGifts wrapped with love\nPiled high\nExcitement in the air\nYou can't deny\n[Chorus]\nWinter whispers in the wind\nJoy and love it brings\nLet's celebrate this season\nWith the ones we're missing", "audio_url": "https://cdn1.suno.ai/b878a87b-a0db-4046-8ccd-ecd2fb3d4372.mp3", "video_url": "https://cdn1.suno.ai/b878a87b-a0db-4046-8ccd-ecd2fb3d4372.mp4", "created_at": "2024-05-11T07:33:05.430Z", "model": "chirp-v3", "prompt": "A song for Christmas", "style": "pop" } ] }
{ "success": true, "task_id": "57e8ce3a-39cb-41a2-802f-e70a324f4d0a", "data": { "text": "[Verse]\nSnowflakes falling from the sky\nWinter's cold touch\nOh how it gets me high\nI bundle up in layers\nOh so cozy\nStepping out and feeling the frost on my nose\nSee\n\n[Verse 2]\nThe world is covered in a blanket of white\nIcicles hanging\nShimmering so bright\nThe chilly air fills my lungs with every breath\nWalking in the snow\nLeaving footprints that won't be left\n\n[Chorus]\nOh\nWinter's cold touch\nIt's a season that I love so much\nSnowfall brings a feeling so divine\nWinter's cold touch\nIt's a magical time", "title": "Winter's Cold Touch", "status": "complete" } }
{ "answer": "I am an AI language model developed by OpenAI and I don't have a personal name. However, you can call me GPT or simply Chatbot. How can I assist you today?" }
{ "answer": "I am an AI language model created by OpenAI and I don't have a personal name. You can simply call me OpenAI or ChatGPT. How can I assist you today?", "id": "7cdb293b-2267-4979-a1ec-48d9ad149916" }
第二次請求,將第一次請求返回的 id 字段作為參數(shù)傳遞,同時 stateful 參數(shù)依然設置為 true,詢問「What I asked you just now?」,如圖所示:
對應代碼如下:
1 2 3 4 5 6 7 8 9 10
curl -X POST 'https://api.acedata.cloud/aichat/conversations' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "gpt-3.5", "stateful": true, "id": "7cdb293b-2267-4979-a1ec-48d9ad149916", "question": "What I asked you just now?" }'
結(jié)果如下:
1 2 3 4
{ "answer": "You asked me what my name is. As an AI language model, I do not possess a personal identity, so I don't have a specific name. However, you can refer to me as OpenAI or ChatGPT, the names used for this AI model. Is there anything else I can help you with?", "id": "7cdb293b-2267-4979-a1ec-48d9ad149916" }
@Override publicvoidonResponse(Call call, Response response)throws IOException { if (!response.isSuccessful()) thrownew IOException("Unexpected code " + response); try (BufferedReader br = new BufferedReader( new InputStreamReader(response.body().byteStream(), "UTF-8"))) { String responseLine; while ((responseLine = br.readLine()) != null) { System.out.println(responseLine); } } } });
其他語言可以另外自行改寫,原理都是一樣的。
模型預設
我們知道,OpenAI 相關的 API 有對應的 system_prompt 的概念,就是給整個模型設置一個預設,比如它叫什么名字等等。本 AI 問答 API 也暴露了這個參數(shù),叫做 preset,利用它我們可以給模型增加預設,我們用一個例子來體驗下:
這里我們額外添加 preset 字段,內(nèi)容為 You are a professional artist,如圖所示:
對應代碼如下:
1 2 3 4 5 6 7 8 9 10
curl -X POST 'https://api.acedata.cloud/aichat/conversations' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "gpt-3.5", "stateful": true, "question": "What can you help me?", "preset": "You are a professional artist" }'
運行結(jié)果如下:
1 2 3
{ "answer": "As a professional artist, I can offer a range of services and assistance depending on your specific needs. Here are a few ways I can help you:\n\n1. Custom Artwork: If you have a specific vision or idea, I can create custom artwork for you. This can include paintings, drawings, digital art, or any other medium you prefer.\n\n2. Commissioned Pieces: If you have a specific subject or concept in mind, I can create commissioned art pieces tailored to your preferences. This could be for personal enjoyment or as a unique gift for someone special.\n\n3. Art Consultation: If you need guidance on art selection, interior design, or how to showcase and display art in your space, I can provide professional advice to help enhance your aesthetic sense and create a cohesive look." }
curl -X POST 'https://api.acedata.cloud/aichat/conversations' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "gpt-4-vision", "question": "How many apples in the picture?", "references": ["https://cdn.acedata.cloud/ht05g0.png"] }'
運行結(jié)果如下:
1 2 3
{ "answer": "There are 5 apples in the picture." }
可以看到,我們就成功得到了對應圖片的回答結(jié)果。
聯(lián)網(wǎng)問答
本 API 還支持聯(lián)網(wǎng)模型,包括 GPT-3.5、GPT-4 均能支持,在 API 背后有一個自動搜索互聯(lián)網(wǎng)并總結(jié)的過程,我們可以選擇模型為 gpt-3.5-browsing 來體驗下,如圖所示:
代碼如下:
1 2 3 4 5 6 7 8
curl -X POST 'https://api.acedata.cloud/aichat/conversations' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "gpt-3.5-browsing", "question": "What's the weather of New York today?" }'
運行結(jié)果如下:
1 2 3
{ "answer": "The weather in New York today is as follows:\n- Current Temperature: 16°C (60°F)\n- High: 16°C (60°F)\n- Low: 10°C (50°F)\n- Humidity: 47%\n- UV Index: 6 of 11\n- Sunrise: 5:42 am\n- Sunset: 8:02 pm\n\nIt's overcast with a chance of occasional showers overnight, and the chance of rain is 50%.\nFor more details, you can visit [The Weather Channel](https://weather.com/weather/tenday/l/96f2f84af9a5f5d452eb0574d4e4d8a840c71b05e22264ebdc0056433a642c84).\n\nIs there anything else you'd like to know?" }
可以看到,這里它自動聯(lián)網(wǎng)搜索了 The Weather Channel 網(wǎng)站,并獲得了里面的信息,然后進一步返回了實時結(jié)果。
在這個數(shù)字化時代,人工智能技術(shù)正以驚人的速度改變著我們的生活方式和創(chuàng)造方式。音樂作為一種最直接、最感性的藝術(shù)形式,自然也成為了人工智能技術(shù)的應用場景之一。今天,我們將以 Vue 和 Node.js 為基礎,利用現(xiàn)有的 API 來快速搭建一個 Suno AI 音樂站點。讓我們一起探索這個令人興奮的過程吧!
<template> <divid="app"> <header> <h1>XiaoZhi AI Music Generator</h1> </header> <main> <divclass="input-container"> <inputtype="text"v-model="musicTitle"placeholder="Enter a prompt for the music"> <button @click="handleGenerateMusic":disabled="loading">生成音樂</button> </div> <divv-if="loading"class="loading"> Music is being generated for you, please wait... </div>
<divv-if="musicGenerated"class="music-container"> <divv-for="music in generatedMusic":key="music.id"class="music-item"> <h2>{{ music.title }}</h2> <img:src="music.image_url"alt="Music Image"> <pclass="lyric">{{ music.lyric }}</p> <audiocontrolsclass="audio" @play="stopOtherMedia($event)"> <source:src="music.audio_url"type="audio/mpeg"> Your browser does not support the audio element. </audio> <videocontrolsclass="video" @play="stopOtherMedia($event)"> <source:src="music.video_url"type="video/mp4"> Your browser does not support the video element. </video> </div> </div>
隨著互聯(lián)網(wǎng)的普及和發(fā)展,海外住宅IP的需求日益增加。個人用戶可以通過使用海外住宅 IP 來訪問特定地區(qū)的新聞、娛樂、教育和文化資源,從而獲得更高的訪問速度、優(yōu)質(zhì)的用戶體驗和更強的網(wǎng)絡安全性。
對于企業(yè)而言,海外住宅IP為進軍國際市場提供了重要的支持。通過了解目標市場的需求和競爭環(huán)境,企業(yè)可以制定相應的營銷策略和產(chǎn)品定位。海外住宅 IP 還有助于企業(yè)進行市場推廣活動,實現(xiàn)定向投放廣告和提供個性化的客戶體驗,從而提升品牌知名度和市場份額。
一、海外住宅 IP 的可靠性
海外住宅 IP 的可靠性主要取決于供應商的信譽和服務質(zhì)量。為了保障用戶的在線安全和隱私,選擇一個可靠的海外住宅 IP 提供商至關重要。在此推薦 SmartProxy,一家優(yōu)質(zhì)海外住宅代理和全球IP資源服務商。SmartProxy 提供穩(wěn)定可靠的服務,而且價格相對較為實惠。注冊即領免費流量:
我們還可以通過 position 參數(shù)控制二維碼的位置,比如說一張圖片里面有一個女生穿裙子,而我們想要把二維碼放在裙子的位置并與之融合起來,我們就可以嘗試改下二維碼的位置,調(diào)用樣例如下:
1 2 3 4 5 6 7 8 9
curl -X POST "https://api.zhishuyun.com/qrart/generate?token={token}" \ -H "accept: application/json" \ -H "content-type: application/json" \ -d '{ "type": "link", "content": "https://data.zhishuyun.com", "prompt": "one of the beautiful girls in the moonlight in the background, in the style of pixelated chaos, rococo-inspired art, dark white and sky-blue, made of plastic, delicate flowers, gongbi, wimmelbilder", "position": "bottom" }'
在這里我們就不再對各種 API 參數(shù)進行一一介紹了,更詳細更實時的內(nèi)容可以參見知數(shù)云的官方文檔,鏈接為:https://data.zhishuyun.com/documents/ee085d2a-a0b9-4f0e-8b4d-8da407345138。
價格
知數(shù)云藝術(shù)二維碼的 API 提供了階梯定價,首次申請免費贈送 20 次,而且購買越多越便宜,由于價格會動態(tài)調(diào)整,所以大家可以查看知數(shù)云官網(wǎng)來查看最新實時價格:https://data.zhishuyun.com/services/38ecf158-36f2-42f2-8e7f-6786cdfc2452
價格怎么樣呢?由于價格可能會動態(tài)變化,大家可以直接參考知數(shù)云的官方網(wǎng)站了解:https://data.zhishuyun.com/services/d87e5e99-b797-4ade-9e73-b896896b0461。但總的來說,能夠以這個價格做到知數(shù)云 Midjourney API 這樣的穩(wěn)定性和并發(fā)的,業(yè)界寥寥無幾,歡迎選購和評測。
這家代理的官方網(wǎng)站是 http://www.ipidea.net/?utm-source=cqc&utm-keyword=?ipidea。從他們的介紹可以看到,他們是一家全球范圍的 IP 代理服務商,能覆蓋全球 220 個國家和地區(qū),大部分代理實際上是住宅 IP。
官方介紹這家的代理 IP 數(shù)量大約是九千萬左右,這個數(shù)量非常龐大,同時官方介紹說代理的可用率是 99.9%。
下面我們來看一下他們的一些套餐類型:
動態(tài)住宅代理:這種代理實際上就是用真實的住宅用戶的 IP 搭建的代理。一般來說,住宅代理對于很多場景的使用封禁概率會比較低,因為很多廠商對封禁住宅代理是比較謹慎的。動態(tài)住宅代理其實就是可以定時切換的 IP,比如說做網(wǎng)絡爬蟲,我們就需要不斷變換的不同的代理 IP,這樣可以進一步的減少被封禁的概率。
靜態(tài)住宅代理:相對于動態(tài)代理來說,靜態(tài)住宅代理的特點就是長效穩(wěn)定,可以一直獲取一個穩(wěn)定不變的代理 IP,適合長久的穩(wěn)定的海外網(wǎng)絡環(huán)境使用。比如說,我們要進行自動化網(wǎng)站的爬取,如果在一個頁面內(nèi) IP 地址頻繁變動會增大被風控的概率。所以,如果有一個長效穩(wěn)定的住宅 IP 代理,就會非常方便。
數(shù)據(jù)中心代理:這種代理實際上是很多服務器廠商的服務器搭建起來的代理。例如騰訊云、阿里云、微軟云等服務器所在的 IP 地址段,就屬于所謂的數(shù)據(jù)中心的 IP 地址段。因此,用這些服務器搭建出來的代理就叫做數(shù)據(jù)中心代理。一般來說,這種數(shù)據(jù)中心代理相對于住宅代理更容易被爬蟲封禁,但是這種代理的優(yōu)勢就是價格更加便宜,而且網(wǎng)絡速度也會相對較好。
I want you to act as a javascript console. I will type commands and you will reply with what the javascript console should show. I want you to only reply with the terminal output inside one unique code block, and nothing else. do not write explanations. do not type commands unless I instruct you to do so. when i need to tell you something in english, i will do so by putting text inside curly brackets {like this}. my first command is console.log(“Hello World”);
import time from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.common.action_chains import ActionChains from app.captcha_resolver import CaptchaResolver
# click captchas recognized_indices = [i for i, x in enumerate(recognized_results) if x] logger.debug(f'recognized_indices {recognized_indices}') click_targets = self.wait.until(EC.visibility_of_all_elements_located( (By.CSS_SELECTOR, '.task-image'))) for recognized_index in recognized_indices: click_target: WebElement = click_targets[recognized_index] click_target.click() time.sleep(random())
import time from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.common.action_chains import ActionChains from app.captcha_resolver import CaptchaResolver
defget_question_id_by_target_name(target_name): logger.debug(f'try to get question id by {target_name}') question_id = CAPTCHA_TARGET_NAME_QUESTION_ID_MAPPING.get(target_name) logger.debug(f'question_id {question_id}') return question_id
single_captcha_elements = self.wait.until(EC.visibility_of_all_elements_located( (By.CSS_SELECTOR, '#rc-imageselect-target table td'))) for recognized_index in recognized_indices: single_captcha_element: WebElement = single_captcha_elements[recognized_index] single_captcha_element.click() # check if need verify single captcha self.verify_single_captcha(recognized_index)
defverify_single_captcha(self, index): time.sleep(3) elements = self.wait.until(EC.visibility_of_all_elements_located( (By.CSS_SELECTOR, '#rc-imageselect-target table td'))) single_captcha_element: WebElement = elements[index] class_name = single_captcha_element.get_attribute('class') logger.debug(f'verifiying single captcha {index}, class {class_name}') if'selected'in class_name: logger.debug(f'no new single captcha displayed') return logger.debug('new single captcha displayed') single_captcha_url = single_captcha_element.find_element_by_css_selector( 'img').get_attribute('src') logger.debug(f'single_captcha_url {single_captcha_url}') with open(CAPTCHA_SINGLE_IMAGE_FILE_PATH, 'wb') as f: f.write(requests.get(single_captcha_url).content) resized_single_captcha_base64_string = resize_base64_image( CAPTCHA_SINGLE_IMAGE_FILE_PATH, (100, 100)) single_captcha_recognize_result = self.captcha_resolver.create_task( resized_single_captcha_base64_string, get_question_id_by_target_name(self.captcha_target_name)) ifnot single_captcha_recognize_result: logger.error('count not get single captcha recognize result') return has_object = single_captcha_recognize_result.get( 'solution', {}).get('hasObject') if has_object isNone: logger.error('count not get captcha recognized indices') return if has_object isFalse: logger.debug('no more object in this single captcha') return if has_object: single_captcha_element.click() # check for new single captcha self.verify_single_captcha(index)
OK,這里我們定義了一個 verify_single_captcha 方法,然后傳入了格子對應的序號。接著我們首先嘗試查找格子對應的節(jié)點,然后找出對應的 HTML 的 class 屬性。如果沒有出現(xiàn)新的小圖,那就是這樣的選中狀態(tài),對應的 class 就包含了 selected 字樣,如圖所示:
比如說,我們有兩臺主機 A、B,我們最終想實現(xiàn)在 A 上控制 B。那么如果用正向 Shell,其實就是在 A 上輸入 B 的連接地址,比如通過 ssh 連接到 B,連接成功之后,我們就可以在 A 上通過命令控制 B 了。如果用反向 Shell,那就是在 A 上先開啟一個監(jiān)聽端口,然后讓 B 去連接 A 的這個端口,連接成功之后,A 這邊就能通過命令控制 B 了。
反彈 Shell 有什么用?
還是原來的例子,我們想用 A 來控制 B,如果想用 ssh 等命令來控制,那得輸入 B 的 sshd 地址或者端口對吧?但是在很多情況下,由于防火墻、安全組、局域網(wǎng)、NAT 等原因,我們實際上是無法直接連接到 B 的,比如:
A 雖然有公網(wǎng) IP,但 B 是一個處于內(nèi)網(wǎng)的機器,A 就沒法直接連到 B 上。
B 上開了防火墻或者安全組限制,sshd 的服務端口 22 被封閉了。
B 是一臺撥號主機,其 IP 地址經(jīng)常變動。
假如 B 被攻擊了,我們想讓 B 向 A 匯報自己的狀況,那自然就需要 B 主動去連接 A。
如果是這些情況,我們就可以用反彈 Shell 用 A 來控制 B 了。
反彈 Shell 案例
首先我們先看一個標準的反彈 Shell 的例子,這里我們一共需要兩臺主機:
A 是控制端,可以處于公網(wǎng)之中,也可以和 B 處于一個局域網(wǎng)中,總之能讓 B 找到 A 就行。
!(function (a, b) { console.log("result", a, b); })(1, 2);
這里我們先聲明了一個 function,然后接收 a 和 b 兩個參數(shù),然后把內(nèi)容輸出出來,然后我們把這個 function 用小括號括起來,這其實就是一個方法,可以被直接調(diào)用的,怎么調(diào)用呢?后面再跟上對應的參數(shù)就好了,比如傳入 1 和 2,執(zhí)行結(jié)果如下:
1
result 12
可以看到,這個自執(zhí)行的方法就被執(zhí)行了。
同理地,crypto-js.min.js 也符合這個格式,它接收 t 和 e 兩個參數(shù),t 就是 this,其實就是瀏覽器中的 window 對象,e 就是一個 function(用于定義 CryptoJS 的核心內(nèi)容)。
接下來我們來看一個簡單的網(wǎng)站:https://login1.scrape.center/,這個網(wǎng)站的結(jié)構(gòu)非常簡單,就是一個用戶名密碼登錄。但是不同的是,點擊登錄的時候,表單提交 POST 的內(nèi)容并不是單純的用戶名和密碼,而是一個加密后的 token。
網(wǎng)頁是運行在瀏覽器端的,當我們?yōu)g覽一個網(wǎng)頁時,其 HTML 代碼、 JavaScript 代碼都會被下載到瀏覽器中執(zhí)行。借助瀏覽器的開發(fā)者工具,我們可以看到網(wǎng)頁在加載過程中所有網(wǎng)絡請求的詳細信息,也能清楚地看到網(wǎng)站運行的 HTML 代碼和 JavaScript 代碼,這些代碼中就包含了網(wǎng)站加載的全部邏輯,如加載哪些資源、請求接口是如何構(gòu)造的、頁面是如何渲染的等等。正因為代碼是完全透明的,所以如果我們能夠把其中的執(zhí)行邏輯研究出來,就可以模擬各個網(wǎng)絡請求進行數(shù)據(jù)爬取了。
網(wǎng)站運營者首先想到防護措施可能是對某些數(shù)據(jù)接口的參數(shù)進行加密,比如說對某些 URL 的一些參數(shù)加上校驗碼或者把一些 id 信息進行編碼,使其變得難以閱讀或構(gòu)造;或者對某些 API 請求加上一些 token、sign 等簽名,這樣這些請求發(fā)送到服務器時,服務器會通過客戶端發(fā)來的一些請求信息以及雙方約定好的秘鑰等來對當前的請求進行校驗,如果校驗通過,才返回對應數(shù)據(jù)結(jié)果。
現(xiàn)在絕大多數(shù)網(wǎng)站的數(shù)據(jù)一般都是通過服務器提供的 API 來獲取的,網(wǎng)站或 App 可以請求某個數(shù)據(jù) API 獲取到對應的數(shù)據(jù),然后再把獲取的數(shù)據(jù)展示出來。但有些數(shù)據(jù)是比較寶貴或私密的,這些數(shù)據(jù)肯定是需要一定層面上的保護。所以不同 API 的實現(xiàn)也就對應著不同的安全防護級別,我們這里來總結(jié)下。
var a = ["hello"]; (function (c, d) { var e = function (f) { while (--f) { c["push"](c["shift"]()); } }; e(++d); })(a, 0x9b); var b = function (c, d) { c = c - 0x0; var e = a[c]; return e; }; let hello = "1" + 0x1; console["log"](b("0x0"), hello);
在一些付費代理套餐中,大家可能會注意到有這樣的一個套餐 - 獨享代理或私密代理,這種其實就是用了專用服務器搭建了代理服務,相對一般的付費代理來說,其穩(wěn)定性更好,速度也更快,同時 IP 可以動態(tài)變化。這種獨享代理或私密代理的 IP 切換大多數(shù)都是基于 ADSL 撥號機制來實現(xiàn)的,一臺云主機每撥號一次就可以換一個 IP,同時云主機上搭建了代理服務,我們就可以直接使用該云主機的 HTTP 代理來進行數(shù)據(jù)爬取了。
本節(jié)我們就來實際操作一下搭建 ADSL 撥號代理服務的方法。
1. 什么是 ADSL
ADSL,英文全稱是 Asymmetric Digital Subscriber Line,即非對稱數(shù)字用戶環(huán)路。它的上行和下行帶寬不對稱,它采用頻分復用技術(shù)把普通的電話線分成了電話、上行和下行 3 個相對獨立的信道,從而避免了相互之間的干擾。
ADSL 通過撥號的方式上網(wǎng),撥號時需要輸入 ADSL 賬號和密碼,每次撥號就更換一個 IP。IP 分布在多個 A 段,如果 IP 都能使用,則意味著 IP 量級可達千萬。如果我們將 ADSL 主機作為代理,每隔一段時間云主機撥號就換一個 IP,這樣可以有效防止 IP 被封禁。另外,由于我們是直接使用專有的云主機搭建的代理服務,所以其代理的穩(wěn)定性相對更好,代理響應速度也相對更快。
首先,在互聯(lián)網(wǎng)上有大量公開的免費代理。當然,我們也可以購買付費的代理 IP,但是代理不論是免費的還是付費的,都不能保證是可用的,因為此 IP 可能被其他人用來爬取同樣的目標站點而被封禁,或者代理服務器突然發(fā)生故障或網(wǎng)絡繁忙。一旦我們選用了一個不可用的代理,這勢必會影響爬蟲的工作效率。
接口模塊:需要用 API 來提供對外服務的接口。其實我們可以直接連接數(shù)據(jù)庫來取對應的數(shù)據(jù),但是這樣就需要知道數(shù)據(jù)庫的連接信息,并且要配置連接,而比較安全和方便的方式就是提供一個 Web API 接口,我們通過訪問接口即可拿到可用代理。另外,由于可用代理可能有多個,所以我們可以設置一個隨機返回某個可用代理的接口,這樣就能保證每個可用代理都可以取到,實現(xiàn)負載均衡。
import redis from proxypool.exceptions import PoolEmptyException from proxypool.schemas.proxy import Proxy from proxypool.setting import REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_KEY, PROXY_SCORE_MAX, PROXY_SCORE_MIN, \ PROXY_SCORE_INIT from random import choice from typing import List from loguru import logger from proxypool.utils.proxy import is_valid_proxy, convert_proxy_or_proxies
defadd(self, proxy: Proxy, score=PROXY_SCORE_INIT) -> int: """ add proxy and set it to init score :param proxy: proxy, ip:port, like 8.8.8.8:88 :param score: int score :return: result """ ifnot is_valid_proxy(f'{proxy.host}:{proxy.port}'): logger.info(f'invalid proxy {proxy}, throw it') return ifnot self.exists(proxy): if IS_REDIS_VERSION_2: return self.db.zadd(REDIS_KEY, score, proxy.string()) return self.db.zadd(REDIS_KEY, {proxy.string(): score})
defrandom(self) -> Proxy: """ get random proxy firstly try to get proxy with max score if not exists, try to get proxy by rank if not exists, raise error :return: proxy, like 8.8.8.8:8 """ # try to get proxy with max score proxies = self.db.zrangebyscore(REDIS_KEY, PROXY_SCORE_MAX, PROXY_SCORE_MAX) if len(proxies): return convert_proxy_or_proxies(choice(proxies)) # else get proxy by rank proxies = self.db.zrevrange(REDIS_KEY, PROXY_SCORE_MIN, PROXY_SCORE_MAX) if len(proxies): return convert_proxy_or_proxies(choice(proxies)) # else raise error raise PoolEmptyException
defdecrease(self, proxy: Proxy) -> int: """ decrease score of proxy, if small than PROXY_SCORE_MIN, delete it :param proxy: proxy :return: new score """ score = self.db.zscore(REDIS_KEY, proxy.string()) # current score is larger than PROXY_SCORE_MIN if score and score > PROXY_SCORE_MIN: logger.info(f'{proxy.string()} current score {score}, decrease 1') if IS_REDIS_VERSION_2: return self.db.zincrby(REDIS_KEY, proxy.string(), -1) return self.db.zincrby(REDIS_KEY, -1, proxy.string()) # otherwise delete proxy else: logger.info(f'{proxy.string()} current score {score}, remove') return self.db.zrem(REDIS_KEY, proxy.string())
defmax(self, proxy: Proxy) -> int: """ set proxy to max score :param proxy: proxy :return: new score """ logger.info(f'{proxy.string()} is valid, set to {PROXY_SCORE_MAX}') if IS_REDIS_VERSION_2: return self.db.zadd(REDIS_KEY, PROXY_SCORE_MAX, proxy.string()) return self.db.zadd(REDIS_KEY, {proxy.string(): PROXY_SCORE_MAX})
defcount(self) -> int: """ get count of proxies :return: count, int """ return self.db.zcard(REDIS_KEY)
defall(self) -> List[Proxy]: """ get all proxies :return: list of proxies """ return convert_proxy_or_proxies(self.db.zrangebyscore(REDIS_KEY, PROXY_SCORE_MIN, PROXY_SCORE_MAX))
defbatch(self, start, end) -> List[Proxy]: """ get batch of proxies :param start: start index :param end: end index :return: list of proxies """ return convert_proxy_or_proxies(self.db.zrevrange(REDIS_KEY, start, end - 1))
if __name__ == '__main__': conn = RedisClient() result = conn.random() print(result)
from retrying import retry import requests from loguru import logger
classBaseCrawler(object): urls = []
@retry(stop_max_attempt_number=3, retry_on_result=lambda x: x is None) deffetch(self, url, **kwargs): try: response = requests.get(url, **kwargs) if response.status_code == 200: return response.text except requests.ConnectionError: return
@logger.catch defcrawl(self): """ crawl main method """ for url in self.urls: logger.info(f'fetching {url}') html = self.fetch(url) for proxy in self.parse(html): logger.info(f'fetched proxy {proxy.string()} from {url}') yield proxy
import pkgutil from .base import BaseCrawler import inspect
# load classes subclass of BaseCrawler classes = [] for loader, name, is_pkg in pkgutil.walk_packages(__path__): module = loader.find_module(name).load_module(name) for name, value in inspect.getmembers(module): globals()[name] = value if inspect.isclass(value) and issubclass(value, BaseCrawler) and value isnot BaseCrawler: classes.append(value) __all__ = __ALL__ = classes
asyncdeftest(self, proxy: Proxy): """ test single proxy :param proxy: Proxy object :return: """ asyncwith aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session: try: logger.debug(f'testing {proxy.string()}') asyncwith session.get(TEST_URL, proxy=f'http://{proxy.string()}', timeout=TEST_TIMEOUT, allow_redirects=False) as response: if response.status in TEST_VALID_STATUS: self.redis.max(proxy) logger.debug(f'proxy {proxy.string()} is valid, set max score') else: self.redis.decrease(proxy) logger.debug(f'proxy {proxy.string()} is invalid, decrease score') except EXCEPTIONS: self.redis.decrease(proxy) logger.debug(f'proxy {proxy.string()} is invalid, decrease score')
@logger.catch defrun(self): """ test main method :return: """ # event loop of aiohttp logger.info('stating tester...') count = self.redis.count() logger.debug(f'{count} proxies to test') for i in range(0, count, TEST_BATCH): # start end end offset start, end = i, min(i + TEST_BATCH, count) logger.debug(f'testing proxies from {start} to {end} indices') proxies = self.redis.batch(start, end) tasks = [self.test(proxy) for proxy in proxies] # run tasks using event loop self.loop.run_until_complete(asyncio.wait(tasks))
if __name__ == '__main__': tester = Tester() tester.run()
這里定義了一個類 Tester,__init__ 方法中建立了一個 RedisClient 對象,供該對象中其他方法使用。接下來,定義了一個 test 方法,這個方法用來檢測單個代理的可用情況,其參數(shù)就是被檢測的代理。注意,test 方法前面加了 async 關鍵詞,這代表這個方法是異步的。方法內(nèi)部首先創(chuàng)建了 aiohttp 的 ClientSession 對象,可以直接調(diào)用該對象的 get 方法來訪問頁面。
測試鏈接在這里定義為常量 TEST_URL。如果針對某個網(wǎng)站有抓取需求,建議將 TEST_URL 設置為目標網(wǎng)站的地址,因為在抓取過程中,代理本身可能是可用的,但是該代理的 IP 已經(jīng)被目標網(wǎng)站封掉了。例如,某些代理可以正常訪問百度等頁面,但是對知乎來說可能就被封了,所以我們可以將 TEST_URL 設置為知乎的某個頁面的鏈接。當請求失敗、代理被封時,分數(shù)自然會減下來,失效的代理就不會被取到了。
如果想做一個通用的代理池,則不需要專門設置 TEST_URL,既可以將其設置為一個不會封 IP 的網(wǎng)站,也可以設置為百度這類響應穩(wěn)定的網(wǎng)站。
defrun_server(self): """ run server for api """ ifnot ENABLE_SERVER: logger.info('server not enabled, exit') return app.run(host=API_HOST, port=API_PORT, threaded=API_THREADED)
defrun(self): global tester_process, getter_process, server_process try: logger.info('starting proxypool...') if ENABLE_TESTER: tester_process = multiprocessing.Process(target=self.run_tester) logger.info(f'starting tester, pid {tester_process.pid}...') tester_process.start()
if ENABLE_GETTER: getter_process = multiprocessing.Process(target=self.run_getter) logger.info(f'starting getter, pid{getter_process.pid}...') getter_process.start()
if ENABLE_SERVER: server_process = multiprocessing.Process(target=self.run_server) logger.info(f'starting server, pid{server_process.pid}...') server_process.start()
tester_process.join() getter_process.join() server_process.join() except KeyboardInterrupt: logger.info('received keyboard interrupt signal') tester_process.terminate() getter_process.terminate() server_process.terminate() finally: # must call join method before calling is_alive tester_process.join() getter_process.join() server_process.join() logger.info(f'tester is {"alive"if tester_process.is_alive() else"dead"}') logger.info(f'getter is {"alive"if getter_process.is_alive() else"dead"}') logger.info(f'server is {"alive"if server_process.is_alive() else"dead"}') logger.info('proxy terminated')
if __name__ == '__main__': scheduler = Scheduler() scheduler.run()
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import WebDriverException import time from loguru import logger
COUNT = 1000
for i in range(1, COUNT + 1): try: browser = webdriver.Chrome() wait = WebDriverWait(browser, 10) browser.get('https://captcha1.scrape.center/') button = wait.until(EC.element_to_be_clickable( (By.CSS_SELECTOR, '.el-button'))) button.click() captcha = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, '.geetest_slicebg.geetest_absolute'))) time.sleep(5) captcha.screenshot(f'data/captcha/images/captcha_{i}.png') except WebDriverException as e: logger.error(f'webdriver error occurred {e.msg}') finally: browser.close()
當前模型的預測過程是通過命令行執(zhí)行的,但在實際使用的時候可能并不太方便,可以考慮將預測過程對接 API 服務器暴露出來,比如對接 Flask、Django、FastAPI 等把預測過程實現(xiàn)為一個支持 POST 請求的接口,接口可以接收一張驗證碼圖片,返回驗證碼的文本信息,這樣會使得模型更加方便易用。
我們在做爬蟲的過程中經(jīng)常會遇到這樣的情況,最初爬蟲正常運行,正常抓取數(shù)據(jù),一切看起來都是那么美好,然而一杯茶的功夫可能就會出現(xiàn)錯誤,比如 403 Forbidden,這時打開網(wǎng)頁一看,可能會看到 “您的 IP 訪問頻率太高” 這樣的提示。出現(xiàn)這種現(xiàn)象的原因是網(wǎng)站采取了一些反爬蟲措施。比如,服務器會檢測某個 IP 在單位時間內(nèi)的請求次數(shù),如果超過了這個閾值,就會直接拒絕服務,返回一些錯誤信息,這種情況可以稱為封 IP。
既然服務器檢測的是某個 IP 單位時間的請求次數(shù),那么借助某種方式來偽裝我們的 IP,讓服務器識別不出是由我們本機發(fā)起的請求,不就可以成功防止封 IP 了嗎?
一種有效的方式就是使用代理,后面會詳細說明代理的用法。在這之前,需要先了解下代理的基本原理,它是怎樣實現(xiàn)偽裝 IP 的呢?
1. 基本原理
代理實際上指的就是代理服務器,英文叫作 Proxy Server,它的功能是代理網(wǎng)絡用戶去取得網(wǎng)絡信息。形象地說,它是網(wǎng)絡信息的中轉(zhuǎn)站。在我們正常請求一個網(wǎng)站時,是發(fā)送了請求給 Web 服務器,Web 服務器把響應傳回給我們。如果設置了代理服務器,實際上就是在本機和服務器之間搭建了一個橋,此時本機不是直接向 Web 服務器發(fā)起請求,而是向代理服務器發(fā)出請求,請求會發(fā)送給代理服務器,然后由代理服務器再發(fā)送給 Web 服務器,接著由代理服務器再把 Web 服務器返回的響應轉(zhuǎn)發(fā)給本機。這樣我們同樣可以正常訪問網(wǎng)頁,但這個過程中 Web 服務器識別出的真實 IP 就不再是我們本機的 IP 了,就成功實現(xiàn)了 IP 偽裝,這就是代理的基本原理。